Skip to content

feat(hive): sponsor-backed account onboarding + ETH anti-drain gate#300

Merged
BitHighlander merged 3 commits into
developfrom
feature/hive-vault
Jun 29, 2026
Merged

feat(hive): sponsor-backed account onboarding + ETH anti-drain gate#300
BitHighlander merged 3 commits into
developfrom
feature/hive-vault

Conversation

@BitHighlander

Copy link
Copy Markdown
Collaborator

Summary

Adds Hive sponsor-backed account onboarding to the vault, with an ETH anti-drain gate.

Onboarding panel (HiveAccountPanel, on the Hive asset page):

  • Resolves the device's active key to a Hive account via Pioneer, or runs the in-app sponsor onboarding wizard when the key controls no account yet.
  • Wizard: live username availability (format + on-chain), device-derived SLIP-0048 role keys, one-tap @keepkey-sponsored on-chain creation. Keys never leave the device; the user pays nothing.

Backend RPCs (bun/index.ts): hiveGetRoleKeys, hiveGetAccount, hiveUsernameAvailable, hiveCreateAccount. hiveCreateAccount derives the four role keys, gets a device owner-signed account_create attestation (op 9), and POSTs to Pioneer's sponsor endpoint. Signing ops route through emuSigningOp on the emulator for the interactive confirm gate.

ETH anti-drain gate: the Hive attestation only proves control of the submitted owner key — not a genuine KeepKey — so a software client could loop fresh keys and drain the sponsor. hiveCreateAccount now also signs a fixed EIP-191 message bound to username+ownerKey with the device ETH key (m/44'/60'/0'/0/0) and sends ethAddress+ethSignature. The server requires the address to hold mainnet ETH (one sponsored account per funded address). A 403 surfaces a dedicated "fund your ETH address" screen rather than a generic error; 409 is disambiguated (name-taken vs address-already-used).

Submodule

Test plan

  • tsc --noEmit clean.
  • hdwallet hive methods: 17 unit tests pass (registry, jspb round-trip, wrappers incl. account_update).
  • On-device smoke (pending): create (200) → same address (409) → unfunded ETH (403) → tampered message/sig (401). Requires Pioneer deployed with HIVE_ETH_GATE + ETHEREUM_RPC_URL.

Hive receive/onboarding panel (HiveAccountPanel) on the Hive asset page:
resolves the device's active key to an account via Pioneer, or runs the
in-app sponsor onboarding wizard (live username availability, device-derived
SLIP-0048 role keys, @keepkey-sponsored on-chain creation; keys never leave
the device).

Backend RPCs: hiveGetRoleKeys, hiveGetAccount, hiveUsernameAvailable,
hiveCreateAccount (device owner-signed account_create attestation -> Pioneer
sponsor endpoint). hiveSignTx/hiveSignAccountCreate route through emuSigningOp
on the emulator for the interactive confirm gate.

ETH anti-drain gate: hiveCreateAccount signs a fixed EIP-191 message bound to
username+ownerKey with the device ETH key (m/44'/60'/0'/0/0) and sends
ethAddress+ethSignature. The server requires the address to hold mainnet ETH
(one sponsored account per funded address) to keep the free service from being
drained. 403 surfaces a dedicated 'fund your ETH address' screen.

Bumps hdwallet 91a9e9d -> d51727e4 (master) for the Hive account-lifecycle
wallet methods (keepkey/hdwallet#50).
…username race

- P1: after a successful create, poll hiveGetAccount (backing off, 90s cap)
  and only hand off to the parent once the account resolves, instead of a
  single 4.5s refresh that could bounce a real success back to the wizard
  when the pubkey->account lookup lagged. Poll halts on unmount.
- P2: surface address-derivation failures instead of an infinite spinner —
  the panel now takes loading/deriveError/onRetryDerive; a null activeKey
  with an error (or no in-flight derive) shows an actionable Retry.
- P2: ignore stale username-availability responses (tag avail with its name +
  latest-name guard) so a late 'available' can't enable creation for a
  different, unchecked name. create() guard hardened to match.
The auto-poll already waited for hiveGetAccount to resolve before handing
off, but the manual 'View account' button still called onCreated blind — a
click before Pioneer resolved the pubkey would refresh()->noAccount->wizard,
unmounting the celebration. Both paths now share a guarded resolveToAccount():
the button does the same lookup, keeps the success screen on noAccount, and
shows a 'still finalizing' hint instead of bouncing.
@BitHighlander BitHighlander merged commit e9e5235 into develop Jun 29, 2026
1 check passed
BitHighlander added a commit that referenced this pull request Jul 1, 2026
)

Adds a Hive entry to the 7.15.0 features in firmware-versions.ts so the firmware
upgrade preview advertises Hive (chain logo + brand color from chains.ts). Vault-side
Hive support already shipped (#300). Consistent with the other deferred-firmware
7.15.0 entries (Zcash, Transaction Insight) — the firmware Hive batch stages separately.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant